
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using XLua;
using Ping = System.Net.NetworkInformation.Ping;

namespace Yoozoo.Framework.Network.Helpers
{
    /// <summary>
    /// Used for storing values inside editor
    /// </summary>
    public class WebsiteSettings
    {
        public List<string> websitesToPing = new List<string>() { "https://www.google.com", "http://www.baidu.com" };
    }
    /// <summary>
    /// Possible results
    /// </summary>
    public enum ConnectionResult
    {
        Working,
        NetorkCardDisabled,
        CannotReachWebsite
    }
    // Application.internetReachability == NetworkReachability.NotReachable; 说明监测到网络关闭了
    // 如果Application.internetReachability 可达，但是ping  google && baidu 失败，说明网络不通
    public class NetStatusHelper:MonoBehaviour
    {
        private static NetStatusHelper instance;
        int availableServers;
        public static NetStatusHelper Instance
        {
            get
            {
                if (instance == null)
                {
                    GameObject go = new GameObject("NetStatusHelper");
                    instance = go.AddComponent<NetStatusHelper>();
                }
                return instance;
            }
        }
        public void CheckNetAvailable(Action<int> completeMethod) 
        {
            if (Application.internetReachability == NetworkReachability.NotReachable)
            {
                completeMethod(1);
                return;
            }

            WebsiteSettings websiteSettings = new WebsiteSettings();

            availableServers = websiteSettings.websitesToPing.Count;
            for (int i = 0; i < websiteSettings.websitesToPing.Count; i++)
            {
                StartCoroutine(TestURL(websiteSettings.websitesToPing[i], completeMethod));
            }
        }
        /// <summary>
        /// Tries to load the url. If success the complete method is triggered 
        /// </summary>
        /// <param name="url"></param>
        /// <param name="completeMethod"></param>
        /// <returns></returns>
        IEnumerator TestURL(string url, Action<int> completeMethod)
        {
            UnityWebRequest www = UnityWebRequest.Get(url);
            yield return www.SendWebRequest();
            if (www.isNetworkError || www.isHttpError || !string.IsNullOrEmpty(www.error))
            {
                ConnectionFailed(completeMethod);       
            }
            else
            {
                completeMethod(0);
                StopAllCoroutines();
            }
        }
        /// <summary>
        /// When all test fail, the fail method is triggered 
        /// </summary>
        /// <param name="completeMethod"></param>
        private void ConnectionFailed(Action<int> completeMethod)
        {
            availableServers--;
            if (availableServers == 0)
            {
                completeMethod(2);
            }
        }

        public  void CheckNetAvailable(string url,Action<int> callback)
        {
            if (string.IsNullOrEmpty(url))
            {
                CheckNetAvailable(callback);
            }
            else
            {
                if (Application.internetReachability == NetworkReachability.NotReachable)
                {
                    if(callback!=null) callback.Invoke(1);
                }
                else
                {
                    CheckChannel(url,callback);
                }
            }
           
        }
        
        public  bool CheckConnectStatus()
        {
            
            return Application.internetReachability != NetworkReachability.NotReachable;
        }

        public  int GetNetType()
        {
            if (Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork)
            {
                //wifi网络
                return 1;
            }
            
            if (Application.internetReachability == NetworkReachability.ReachableViaCarrierDataNetwork)
            {
                //移动网络
                return 2;
            }

            return 0;
        }

        public async void CheckChannel(string url,Action<int> callback)
        {
            bool isSucceed = false;
            Ping ping = new Ping();
            try
            {
                var pingReply = await ping.SendPingAsync(url,2);
                
                if (pingReply != null && pingReply.Status == IPStatus.Success)
                {
                    isSucceed = true;
                }
            }
            catch
            {
                isSucceed  = false;
            }
            if (callback != null)
            {
                callback.Invoke(isSucceed?0:2);
            }
        }

    }
}